package com.im.interceptor;

import com.im.MDA;
import com.im.util.AESEncryptUtil;
import com.im.util.StringUtil;
import net.sf.json.JSONObject;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.LinkedHashSet;
import java.util.Set;

@Aspect
@Component
public class InfoManageMethodInterceptor {

	private static final Logger logger = LogManager.getLogger(InfoManageMethodInterceptor.class);

	@Pointcut("execution(* com.im.controller..*(..))")
	public void controllerMethodPointcut() {
	}

	// 指定拦截器规则；也可以直接把“execution(*
											// com.xjj.........)”写进这里
	@Around("controllerMethodPointcut()") 
	public Object Interceptor(ProceedingJoinPoint pjp) {
		MethodSignature signature = (MethodSignature) pjp.getSignature();
		Method method = signature.getMethod(); // 获取被拦截的方法
		String methodName = method.getName(); // 获取被拦截的方法名

		Set<Object> allParams = new LinkedHashSet<>(); // 保存所有请求参数，用于输出到日志中

		logger.info("请求开始，方法：{}", methodName);

		Object result = null;

		Object[] args = pjp.getArgs();
		String jsonStr="";
		for (int i = 0; i < args.length; i++) {
			if(args[i]==null)
				continue;
			logger.debug("arg: {}", args[i]);
			logger.debug(args[i].getClass());
			// 进行解密
			try {
			if (args[i] instanceof String && "Y".equals(MDA.SWITCH_AES_ENCRIPT_DECRIPT)) {

					JSONObject jsonObject = JSONObject
							.fromObject(AESEncryptUtil.Decrypt(JSONObject.fromObject(args[i]).getString("encryptMsg")));
					args[i] = jsonObject.toString();
			   }else if("Y".equals(MDA.SWITCH_AES_ENCRIPT_DECRIPT)){
				if(StringUtil.isBlank(jsonStr)){
					jsonStr= AESEncryptUtil.Decrypt(JSONObject.fromObject(args[i]).getString("encryptMsg"));
				}
				JSONObject jsonobject = JSONObject.fromObject(jsonStr);
                args[i]= JSONObject.toBean(jsonobject,args[i].getClass());
			   }
				} catch (Exception e) {
					logger.error("调用服务:" + methodName + ",入参解密失败，请检查!" + e.getMessage());
				}


		}

		try {
			// 一切正常的情况下，继续执行被拦截的方法
			//result = pjp.proceed();
			result = pjp.proceed(args);
			
			if(result != null && result.toString().startsWith("{")){
				return handlerResultResolver(result);
			}			
		} catch (Throwable e) {
			logger.info("InfoManageMethodInterceptor "+methodName+" exception: ", e);
		}
		return result;
	}


	/**
	 * 处理出参
	 */
	private Object handlerResultResolver(Object object) {
		if ("Y".equals(MDA.SWITCH_AES_ENCRIPT_DECRIPT)) {
			JSONObject jo = new JSONObject();
			try {
				jo.element("encryptMsg", AESEncryptUtil.Encrypt(object.toString()));
			} catch (Exception e) {
				logger.error("==InfoManageMethodInterceptor handlerResultResolver error." + e.getMessage());
				return object;
			}
			return jo.toString();
		} else {
			return object;
		}
	}
	
	
	private JSONObject handlerParameterResolver(MethodInvocation method) {
		JSONObject jsonObject = null;
		Annotation[][] annotations = method.getMethod().getParameterAnnotations();
		int idx = -1;
		if (annotations != null) {
			for (int i = 0; i < annotations.length; i++) {
				if (annotations[i] != null && annotations[i].length > 0) {
					Annotation[] array = annotations[i];
					for (int j = 0; j < array.length; j++) {
						if ("RequestBody".equals(array[j].annotationType().getSimpleName())) {
							idx = i;
							break;
						}
					}
				}
				if (idx > -1) {
					break;
				}
			}
		}
		if (idx > -1) {
			// 获取参数
			Object body = method.getArguments()[idx];
			if (body != null) {
				// 获取参数类型
				Class classType = method.getMethod().getParameterTypes()[0];
				logger.debug("parameter type:" + classType.getName());
				logger.debug("parameter value:" + body);
				// 进行解密
				if ("Y".equals(MDA.SWITCH_AES_ENCRIPT_DECRIPT)) {
					try {
						jsonObject = JSONObject.fromObject(
								AESEncryptUtil.Decrypt(JSONObject.fromObject(body).getString("encryptMsg")));
					} catch (Exception e) {
						logger.error("调用服务:" + method.getMethod().getName() + ",入参解密失败，请检查!" + e.getMessage());
					}
				}
			} else {
				jsonObject = new JSONObject();
				logger.error("调用服务:" + method.getMethod().getName() + ",入参为Null，请检查!");
			}

			// 重新设置值
			method.getArguments()[idx] = jsonObject;
		} else {
			jsonObject = new JSONObject();
		}

		return jsonObject;
	}

}
